/**
 * @file app\tasks\mobus\mobus_device.c
 *
 * Copyright (C) 2023
 *
 * mobus_device.c is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */

/*---------- includes ----------*/
#include "mobus_device.h"
#include "inc/mobus.h"
#include "options.h"
#include "protocol_mobus.h"
#include "resources.h"
#include "storage.h"
#include <stdio.h>
#include <stdlib.h>


/*---------- macro ----------*/
#define TAG "MobusDevice"

/*---------- type define ----------*/
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
extern bool mobus_channel_evt_cb(mobus_device_t self, protocol_mobus_evt_t evt,
    mobus_ack_result_t* result);
static void _init(mobus_device_t self, serial_transport_t mobus);
static void _get_device_data(mobus_device_t self);
static void __channel_conf(uint8_t sub_channel);
extern bool mobus_dev_evt_cb(mobus_device_t self, protocol_mobus_evt_t evt,
    mobus_ack_result_t* result);
/*---------- function-mobus_device ----------*/
#include "_ack.c"
#include "_config_device.c"
#include "_config_parameter.c"
#include "_mobus_command.c"
#include "_multicast.c"
#include "_passthrough.c"
#include "_report_status.c"
#include "_req_access_to_network.c"
#include "_restore_factory.c"
#include "_upgrade.c"


/*---------- variable ----------*/

struct mobus_device mobus_device = {
    .mobus = NULL,
    .login = MOBUS_LOGGING_IN,
    .init = _init,
    .get_device_data = _get_device_data,
    .req_access_to_mobus_network = _req_access_to_network,
    .ack = _ack,
    .report_information =  _report_channlx_information,   
    .multicast = _multicast,
    .command = _mobus_command,
    .get_parameters = __config_parameters_report,
    .set_parameters = __config_parameters_set,
    .config_device = _config_device,
    .report_status = _report_status,
    .restore_factory = _restore_factory,
    .factory_test = NULL,
    .upgrade = _upgrade,
    .passthrough = _passthrough,
    .evt_cb = NULL,
};
struct storage_mobus_device* modbus_dev = NULL;

/*---------- function ----------*/
static void _get_device_data(mobus_device_t self) {
    modbus_dev = storage_get(STORAGE_AREA_DEVICE);
    assert(modbus_dev);
    /* get device */
    self->device_type = modbus_dev->device.device_type;
    self->native_address = modbus_dev->device.native_address;
    self->version =
        ((MOBUS_LOGIN_VER_MAJOR & 0x07) << 5) | (MOBUS_LOGIN_VER_MINOR & 0x1F);
    self->channel_nums = modbus_dev->device.channel_nums;
    /* get channels */
    for (char i = 1; i < self->channel_nums; i++) {
        self->device_channl_type[i] = modbus_dev->device.channel_type[i];
    }
}
static void __reg_mobus_dev_evt_cb(mobus_device_t self) {
    self->evt_cb = mobus_dev_evt_cb;
}

static void _init(mobus_device_t self, serial_transport_t mobus) {
    assert(self);
    assert(mobus);
    self->mobus = mobus;
    _get_device_data(self);
    __reg_mobus_dev_evt_cb(self);
}
